package pacs_server

import (
	"encoding/json"
	"errors"
	"fmt"
	"gitee.com/uni-minds/bridge-pacs/global"
	"gitee.com/uni-minds/bridge-pacs/tools"
	"github.com/gohouse/gorose/v2"
)

// region Func Instance

func (pi *PacsServer) FindInstanceByIdLocal(id string) (info global.InstanceInfo, err error) {
	data, err := pi.DbInstanceHandler().Where("instance_id", id).First()
	if err != nil {
		return info, err
	}
	info, err = pi.decodeInstanceInfo(data)
	if err != nil {
		return info, err
	} else if info.InstanceId != id {
		return info, errors.New("empty result, not found")
	} else {
		return info, err
	}
}

// 防止数据查询参数过多，sql异常，明确step
func (pi *PacsServer) FindInstanceByIdsLocal(ids []string, step int) (infos []global.InstanceInfo, err error) {
	var data []interface{}
	for _, instanceId := range ids {
		data = append(data, instanceId)
	}

	if step < 1 {
		step = 1000
	}

	ret := make([]gorose.Data, 0)

	for {
		if len(data) < step {
			tmp, err := pi.DbInstanceHandler().WhereIn("instance_id", data).Get()
			if err != nil {
				pi.Log("db find instance by ids failed:", err.Error())
			}
			ret = append(ret, tmp...)
			break
		} else {
			tmp, err := pi.DbInstanceHandler().WhereIn("instance_id", data[:step]).Get()
			if err != nil {
				pi.Log("db find instance by ids failed:", err.Error())
			}
			ret = append(ret, tmp...)
			data = data[step:]
		}
	}

	infos, err = pi.decodeInstanceInfos(ret)
	if err != nil {
		return nil, err
	}

	return infos, nil
}
func (pi *PacsServer) FindInstancesByViewFuzzy(view string) (infos []global.InstanceInfo, err error) {
	if view == "" {
		return nil, errors.New("empty view given")
	}

	selector := fmt.Sprintf("%%%s%%", view)
	data, err := pi.DbInstanceHandler().Where("label_view", "like", selector).Get()
	if err != nil {
		return nil, err
	} else {
		return pi.decodeInstanceInfos(data)
	}
}
func (pi *PacsServer) FindInstancesByView(view string) (infos []global.InstanceInfo, err error) {
	if view == "" {
		return nil, errors.New("empty view given")
	}

	selector := fmt.Sprintf("%s", view)
	h := pi.DbInstanceHandler()
	h.Where("label_view", selector)

	// SELECT * FROM `pacs_server1_instance` WHERE `db_hidden` = ? and `db_delete` = ? and `label_view` = ?, [0 0 3V]
	// select * from tb_test_case where data = 'a'  COLLATE NOCASE;

	data, err := h.Get()
	pi.Log("SQL:", h.LastSql())
	if err != nil {
		return nil, err
	} else {
		return pi.decodeInstanceInfos(data)
	}
}

func (pi *PacsServer) RemoveInstance(instanceId string) (err error) {
	info, err := pi.FindInstanceByIdLocal(instanceId)
	if err != nil {
		return err
	} else if info.SeriesId == "" {
		return errors.New(fmt.Sprintf("E instance %s has empty series id", instanceId))
	}

	if err = pi.dbRemoveInstance(instanceId); err != nil {
		return err
	} else {
		return pi.SeriesRemoveInstanceId(info.SeriesId, instanceId)
	}
}

func (pi *PacsServer) InstanceUpdateLabelCore(instanceId string, data map[string]interface{}) (err error) {
	data["label_update_datetime"] = tools.TimeEncodeNow()
	return pi.dbUpdateInstance(instanceId, data)
}
func (pi *PacsServer) InstanceUpdateAll(id string, info global.InstanceInfo) (err error) {
	var data map[string]interface{}
	bs, _ := json.Marshal(info)
	if err = json.Unmarshal(bs, &data); err != nil {
		return err
	}
	return pi.dbUpdateInstance(id, data)
}
func (pi *PacsServer) InstanceUpdateLabelTag(id, key, value string) (err error) {
	data := map[string]interface{}{key: value}
	return pi.InstanceUpdateLabelCore(id, data)
}

func (pi *PacsServer) InstanceUpdateLabel(instanceId string, label global.LabelInstance) (err error) {
	instanceInfo, err := pi.FindInstanceByIdLocal(instanceId)
	if err != nil {
		return err
	}

	ok, err := pi.CheckSeriesPermissionAuthor(instanceInfo.SeriesId, label.Uid)
	if err != nil {
		return err
	}

	if !ok && !label.OpOverride {
		return errors.New("no permission, wrong user without override")
	}

	if label.OpRemove {
		instanceInfo.LabelView = ""
		instanceInfo.LabelDiagnose = ""
		instanceInfo.LabelInterfere = ""
		instanceInfo.LabelMemo = ""
		instanceInfo.LabelInfoAttend = ""
	} else {
		instanceInfo.LabelView = label.View
		instanceInfo.LabelDiagnose = label.Diagnose
		instanceInfo.LabelInterfere = label.Interfere
		instanceInfo.LabelMemo = label.Memo
		instanceInfo.LabelInfoAttend = label.InfoAttend
	}

	return pi.InstanceUpdateAll(instanceId, instanceInfo)
}
func (pi *PacsServer) InstanceUpdateLabelMemo(instanceId string, memo string) (err error) {
	return pi.InstanceUpdateLabelTag(instanceId, "label_memo", memo)
}
